#!/bin/sh

pass1="commit sh modified baseline baseline-passed baseline-failed --baseline --baseline-passed --baseline-failed"
pass2="add check diffs results recheck upgrade patch install clean keys kill demolish purge uninstall downgrade upgrade transmogrify status check-clean shutdown"

if test $# = 0; then
    cat <<EOF
Usage:
   <operation> <operation> ... <arg> <arg>
where <operation is>
  sh <domain>
  ${pass2} ... <test> ...
To enable completion:
  complete -o filename -C './kvm' ./kvm
EOF
    exit 1
fi

# Invoked by completer with:
#   $0 <command==$0> <word> <previous>?
if test "$1" == $0 -a "$#" -eq 3 ; then
    command=$1
    word=$2
    previous=$3
    # hack to detect first vs later argument
    if test "${previous}" == "${command}" ; then
	# first command
	compgen -W "${pass1} ${pass2}" "${word}" | sort
    elif test "${previous}" == "sh" ; then
	# pass 1 command
	compgen -W "east west north south road build base nic" "${word}"
    else
	# either <command> or <directory>
	compgen -o plusdirs -W "${pass2}" "${word}"
    fi
    exit 0
fi

# accumulate pass 2 commands; execute pass 1 commands

ops=
modified=
baseline=
__baseline=$(sed -n -e 's/^KVM_BASELINE.*=/--baseline /p' Makefile.inc.local)

while test $# -gt 0 ; do
    case " ${pass2} " in
	*" $1 "* ) ops="${ops} $1" ;;
	* )
	    # must be a pass1 command
	    case "$1" in
		--baseline* )
		    baseline=$(expr $1 : '--\(.*\)')
		    shift
		    __baseline="--baseline $1"
		    ;;
		# aliases for pass2 commands
		diff ) ops="${ops} diffs" ;;
		result ) ops="${ops} results" ;;
		test ) ops="${ops} check" ;;
		retest ) ops="${ops} recheck" ;;
		test-clean ) ops="${ops} check-clean" ;;
		# git wrappers
		commit ) shift ; exec git commit "$@" ;;
		# invoke now
		sh ) exec gmake kvmsh-$2 ;;
		# wrappers
		modified )
		    modified=$(git status testing/pluto/ \
				   | awk '/(modified|deleted|renamed):/ { print $NF }' \
				   | grep '/.*/.*/' \
				   | cut -d/ -f1-3 \
				   | sort -u)
		    if test -z "${modified}" ; then
			echo "no modified tests" 1>&2
			exit 1
		    fi
		    ;;
		baseline | baseline-passed | baseline-failed )
		    if test -z "${__baseline}" ; then
			echo "no KVM_BASELINE" 1&2
			exit 1
		    fi
		    baseline=$1
		    ;;
		* ) # check first trailing argument is a directory
		    if test ! -d "$1" ; then
			if test -z "${ops}" ; then
			    echo "unknown command: $1" 1>&2
			else
			    echo "not a directory: $1" 1>&2
			fi
			exit 1
		    fi
		    break
	    esac
	    ;;
    esac
    shift
done

if test -n "${modified}" ; then
    if test -z "${ops}" ; then
	echo "${modified}"
	exit 0
    elif test $# -ne 0 ; then
	echo "both modified and tests specified" 1>&2
	exit 1
    fi
    set ${modified}
elif test $# -eq 0 ; then
    set testing/pluto
fi

if test -z "${ops}" ; then
    echo "nothing to do!" 1>&2
    exit 1
fi

results_command()
{
    if test -n "${baseline}" ; then
	./testing/utils/kvmresults.py ${__baseline} "$@" \
	    | grep --line-buffered -v -e baseline:untested \
	    | grep --line-buffered -e ${baseline}
    else
	./testing/utils/kvmresults.py ${__baseline} "$@"
	status=$?
    fi
}

diffs_command()
{
    if test -n "${baseline}" ; then
	./testing/utils/kvmresults.py ${__baseline} --stats none "$@" \
	    | grep --line-buffered -v -e baseline:untested \
	    | grep --line-buffered -e "${baseline}" \
	    | while read test eol ; do
	    ./testing/utils/kvmresults.py --stats none --print diffs ${test}
	done
    else
	./testing/utils/kvmresults.py --stats none --print diffs "$@"
	status=$?
    fi
}

# second pass
status=0
for op in ${ops} ; do
    case ${op} in
	add )
	    git add "$@"
	    ;;
	kill )
	    gmake kvm-${op}
	    ;;
	upgrade | clean | install | demolish | purge | uninstall | downgrade | upgrade | transmogrify | status | check-clean | shutdown )
	    gmake kvm-${op} || exit $?
	    ;;
	check | recheck )
	    gmake kvm-${op} KVM_TESTS="$*" || exit $?
	    ;;
	diffs )
	    diffs_command "$@"
	    ;;
	results )
	    results_command "$@"
	    ;;
	patch )
	    diffs_command "$@" | patch -p1
	    ;;
	keys )
	    gmake kvm-keys-clean kvm-keys
    esac
done

exit ${status}
